//
//  T3FMAPOIManager.swift
//  t3_map
//
//  Created by Cunhai Li on 2024/12/12.
//

import Foundation
import AMapSearchKit
import Flutter

class T3FMAPOIManager: NSObject {

    private let search = AMapSearchAPI()
    private var strongSelf: T3FMAPOIManager?
    private var result: FlutterResult?

    func regeo(arguments: Any?, result: @escaping FlutterResult) {
        self.result = result

        /// arguments示例：
        /// ```
        /// {
        ///    "longitude": 11.111
        ///    "latitude": 11.111
        /// }
        /// `
        do {
            let json = try T3FJsonUtil.toJson(arguments)
            if let coordinate = jsonToCoordinate2D(json: json) {
                if let search = search {
                    //构建request
                    let request = AMapReGeocodeSearchRequest()
                    request.location = AMapGeoPoint.location(withLatitude: coordinate.latitude, longitude: coordinate.longitude)
                    request.requireExtension = false

                    /// 保持引用
                    strongSelf = self
                    search.delegate = self
                    search.aMapReGoecodeSearch(request)
                }
                else {
                    let response = ["error": T3FMAPOIManagerError.mapSearchInitFail.localizedDescription]
                    let value = try? T3FJsonUtil.toString(response)
                    self.result?(value)
                }
            }
            else {
                let response = ["error": T3FMAPOIManagerError.dataParseFail.localizedDescription]
                let value = try? T3FJsonUtil.toString(response)
                self.result?(value)
            }
        } catch (let error) {
            let response = ["error": error.localizedDescription]
            let value = try? T3FJsonUtil.toString(response)
            self.result?(value)
        }
    }

    private func jsonToCoordinate2D(json: [String: Any]) -> CLLocationCoordinate2D? {
        guard let longitude = json["longitude"] as? Double,
              let latitude = json["latitude"] as? Double
        else { return nil }

        return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }

    deinit {
        print("deinit poi manager")
    }
}

extension T3FMAPOIManager: AMapSearchDelegate {

    func onReGeocodeSearchDone(_ request: AMapReGeocodeSearchRequest!, response: AMapReGeocodeSearchResponse!) {

        defer { strongSelf = nil }

        if let regeocode = response.regeocode {
            var json = [String : Any]()

            if let cityCode = regeocode.addressComponent.citycode {
                json["cityCode"] = cityCode
            }

            if let city = regeocode.addressComponent.city {
                json["city"] = city
            }

            if let adCode = regeocode.addressComponent.adcode {
                json["adCode"] = adCode
            }

            if let district = regeocode.addressComponent.district {
                json["district"] = district
            }

            if let address = regeocode.formattedAddress {
                json["address"] = address
            }

            if let poiName = regeocode.pois?.first?.name {
                json["shortAddress"] = poiName
            }

            let value = try? T3FJsonUtil.toString(json)
            self.result?(value)
        }
        else {
            let response = ["error": T3FMAPOIManagerError.noResult.localizedDescription]
            let value = try? T3FJsonUtil.toString(response)
            self.result?(value)
        }
    }


    func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {

        defer { strongSelf = nil }

        let response = ["error": error.localizedDescription]
        let value = try? T3FJsonUtil.toString(response)
        self.result?(value)
    }
}


private enum T3FMAPOIManagerError: Error {
    case dataParseFail
    case mapSearchInitFail
    case noResult
}

extension T3FMAPOIManagerError: CustomStringConvertible {

    var description: String {
        switch self {
        case .dataParseFail:
            return "数据解析异常"
        case .mapSearchInitFail:
            return "AMapSearchAPI 初始化失败"
        case .noResult:
            return "未查询到逆地理信息"
        }
    }
}
